import { getChatHistory, getChatHistoryRecently, sendFile, sendText } from '@/api/chat'
import short from 'short-uuid'
import { computeFileMd5 } from '@/utils'
// TODO: 再配置文件中
const limit = 20
const state = {
  chatHistory: {},
  historyOffset: {},
  requested: new Set() // 已经请求过的聊天记录
}

const mutations = {

  SET_CHAT_HISTORY: (state, data) => {
    const { contactId, chatMsg } = data
    const msgList = Array.isArray(chatMsg) ? chatMsg : [chatMsg]
    state.chatHistory = {
      ...state.chatHistory,
      [contactId]: msgList
    }
  },
  INSERT_CHAT_MSG: (state, { contactId, chatMsg }) => {
    const msgList = Array.isArray(chatMsg) ? chatMsg : [chatMsg]
    if (!state.chatHistory[contactId]) {
      state.chatHistory = {
        ...state.chatHistory,
        [contactId]: msgList
      }
    } else {
      state.chatHistory[contactId].unshift(...msgList)
    }
  },
  APPEND_CHAT_MSG: (state, { contactId, chatMsg }) => {
    const msgList = Array.isArray(chatMsg) ? chatMsg : [chatMsg]
    if (!state.chatHistory[contactId]) {
      state.chatHistory = {
        ...state.chatHistory,
        [contactId]: msgList
      }
    } else {
      state.chatHistory[contactId].push(...msgList)
    }
  },
  UPDATE_CHAT_MSG: (state, { contactId, chatMsg }) => {
    const chatHistoryList = state.chatHistory[contactId]
    if (!Array.isArray(chatHistoryList)) {
      state.chatHistory = {
        ...state.chatHistory,
        [contactId]: [chatMsg]
      }
    } else {
      const { uuid } = chatMsg
      const idx = chatHistoryList.findIndex(item => item.uuid === uuid)
      if (idx !== -1) {
        chatHistoryList.splice(idx, 1, { ...chatHistoryList[idx], ...chatMsg })
      }
      console.log('update chat msg-----', chatMsg)
    }
  },
  ADD_REQUESTED: (state, contactId) => {
    state.requested.add(contactId)
  },
  INCREASE_HISTORY_OFFSET: (state, { contactId, amount }) => {
    if (!state.historyOffset[contactId]) {
      state.historyOffset[contactId] = amount
    } else {
      state.historyOffset[contactId] = state.historyOffset[contactId] + amount
    }
  }
}

const actions = {

  async initChatHistory({ commit, state, dispatch }, contactId) {
    const hasInited = state.requested.has(contactId)
    if (state.chatHistory[contactId] && hasInited) return
    const { data } = await getChatHistoryRecently(contactId)
    let len = data.length
    if (len > 0) {
      commit('SET_CHAT_HISTORY', { contactId, chatMsg: data })
    } else {
      len = await dispatch('getChatHistory', contactId)
    }
    commit('ADD_REQUESTED', contactId)
    return len
  },
  async getChatHistory({ commit, state }, contactId) {
    const offset = state.historyOffset[contactId] || 0
    const { data } = await getChatHistory({ contactId, offset, limit })
    commit('INSERT_CHAT_MSG', { contactId, chatMsg: data })
    commit('INCREASE_HISTORY_OFFSET', { contactId, amount: data.length })
    return data.length
  },
  // 生成发送的数据，并同步本地数据
  async genSendData({ commit, rootGetters, dispatch }, payload) {
    const date = (new Date()).toISOString()
    const sendChatMsg = {
      avatar: rootGetters.userInfo.avatar,
      createdAt: date,
      from: rootGetters.userInfo.id,
      uuid: short.generate(),
      ...payload
    }
    let localChatMsg = sendChatMsg
    if (['audio', 'image'].includes(sendChatMsg.type)) {
      localChatMsg = {
        ...sendChatMsg,
        url: (window.URL || window.webkitURL).createObjectURL(sendChatMsg.file)
      }
    }
    commit('APPEND_CHAT_MSG', {
      contactId: localChatMsg.to,
      chatMsg: localChatMsg
    })
    await dispatch('chatList/updateChatItem', { contactId: localChatMsg.to, chatMsg: localChatMsg })
    return sendChatMsg
  },

  // 接收到文字信息
  async socket_text({ commit, dispatch }, chatMsg) {
    commit('APPEND_CHAT_MSG', { contactId: chatMsg.from, chatMsg })
    await dispatch('chatList/updateChatItem', { contactId: chatMsg.from, chatMsg })
    return chatMsg
  },

  // 接收到语音信息
  async socket_audio({ commit, dispatch }, chatMsg) {
    console.log('接收到audio----', chatMsg)
    commit('APPEND_CHAT_MSG', { contactId: chatMsg.from, chatMsg })
    await dispatch('chatList/updateChatItem', { contactId: chatMsg.from, chatMsg: { ...chatMsg, content: '[语音]' }})
    return chatMsg
  },
  // 接收到图片信息
  async socket_image({ commit, dispatch }, chatMsg) {
    commit('APPEND_CHAT_MSG', { contactId: chatMsg.from, chatMsg })
    await dispatch('chatList/updateChatItem', { contactId: chatMsg.from, chatMsg: { ...chatMsg, content: '[图片]' }})
    return chatMsg
  },
  // 接收到文件
  async socket_file({ commit, dispatch }, chatMsg) {
    console.log('接受到文件-----', chatMsg)
    commit('APPEND_CHAT_MSG', { contactId: chatMsg.from, chatMsg })
    await dispatch('chatList/updateChatItem', { contactId: chatMsg.from, chatMsg: { ...chatMsg, content: '[图片]' }})
    return chatMsg
  },
  // 发送文件
  async sendFile({ dispatch, commit }, { file, to, type = 'file' }) {
    console.log('file----', file)
    const md5 = await computeFileMd5(file)
    console.log('md5---', md5)
    const chatMsg = await dispatch('genSendData', {
      to: to,
      fileName: file.name,
      size: file.size,
      type,
      loaded: 0,
      md5,
      file: file
    })
    console.log('genSendData---', chatMsg)
    // eslint-disable-next-line no-unused-vars
    const { content, loaded, ...sendForm } = chatMsg
    try {
      const { code } = await sendFile(sendForm, (e) => {
        // TODO: 这里需要节流
        console.log('上传事件----', e)
        const { loaded, total } = e
        const loadedPercent = Math.floor(loaded * 100 / total)
        commit('UPDATE_CHAT_MSG', {
          contactId: to,
          chatMsg: { uuid: chatMsg.uuid, loaded: loadedPercent }
        })
      })
      if (code !== 0) {
        // TODO: 文件发送异常处理
      }
    } catch (e) {
      // TODO: 文件发送异常处理
    }
  },

  // 发送文字
  async sendText() {

  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}

